package br.com.sgc.session;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;

import br.com.sgc.dao.PedidoCompraDao;
import br.com.sgc.entities.financeiro.ItemCompra;
import br.com.sgc.entities.financeiro.PedidoCompra;
import br.com.sgc.entities.geral.Clinica;
import br.com.sgc.entities.produto.Fornecedor;
import br.com.sgc.entities.produto.ProdutoFinal;
import br.com.sgc.enuns.TipoOrdenacao;
import br.com.sgc.exception.ValidacaoException;

@Stateless
public class PedidoCompraSession extends GenericSession<PedidoCompra> {

	private static final long serialVersionUID = 4661870885878654225L;
	
	@EJB private PedidoCompraDao dao;
	
	@EJB private ItemCompraSession itemCompraSession;
	
	@EJB private ProdutoFinalSession produtoFinalSession;
	
	@EJB private CaixaSession caixaSession;
	
	public PedidoCompra fillPedidoCompra(PedidoCompra pedidoCompra, Fornecedor fornecedor, Clinica clinica, Boolean finalizado, Boolean cancelado, Boolean guardado) {
		if(pedidoCompra.getId() != null){
			pedidoCompra = dao.findById(PedidoCompra.class, pedidoCompra.getId(), true);
		} else {
			pedidoCompra.setFornecedor(fornecedor);
			pedidoCompra.setClinica(clinica);
			pedidoCompra.setValorDesconto(new BigDecimal(0.0));
			calculateNumeroPedido(pedidoCompra);
			pedidoCompra.setDataCompra(new Date());
		}
		pedidoCompra.setFinalizado(finalizado);
		pedidoCompra.setGuardado(guardado);
		pedidoCompra.setCancelado(cancelado);
		dao.detach(pedidoCompra);
		
		return pedidoCompra;
		
	}
	
	private void calculateNumeroPedido(PedidoCompra pedido) {
		if(pedido.getNumeroPedido() == null && pedido.getIndexNumeroPedido() == null){
			pedido.setIndexNumeroPedido(dao.findLastIndex()+1);
			pedido.setNumeroPedido(pedido.getIndexNumeroPedido()+"-PED");
		}
	}
	
	public List<PedidoCompra> findAll(PedidoCompra modelClass, Long clinicaId,
			Integer startPage, Integer maxPage, String orderField,
			Boolean initializeDependecies, TipoOrdenacao ordenacao) {
		return dao.findAll(modelClass, clinicaId, startPage, maxPage, orderField,
				initializeDependecies, ordenacao);
	}
	
	@Override
	public Long count(PedidoCompra modelClass, Long clinicaId) {
		return dao.count(modelClass, clinicaId);
	}

	public void guardarPedido(PedidoCompra pedidoCompra) throws ValidacaoException {
		pedidoCompra.setAtualizouEstoque(false);
		dao.insert(pedidoCompra);
	}

	public void cancelarPedido(PedidoCompra t) throws ValidacaoException {
		caixaSession.caixaFechado(t.getClinica());
		if(t.getAtualizouEstoque() == null || !t.getAtualizouEstoque()){
			for(ItemCompra item: t.getProdutos()){
				ProdutoFinal produto = item.getProduto();
				if(produto.getEstoqueAtual() == null){
					produto.setEstoqueAtual(0.0);
				}
				produto.setEstoqueAtual(produto.getEstoqueAtual()-item.getQuantidade());
				if(produto.getEstoqueAtual() < 0){
					produto.setEstoqueAtual(0.0);
				}
				produto = produtoFinalSession.update(produto);
				
			}
		}
		t = dao.update(t);
		atualizarCustoMedio(t);
		
	}
	
	@Override
	public PedidoCompra save(PedidoCompra t) throws ValidacaoException {
		caixaSession.caixaFechado(t.getClinica());
		
		if(t.getAtualizouEstoque() == null || !t.getAtualizouEstoque()){
			for(ItemCompra item: t.getProdutos()){
				ProdutoFinal produto = item.getProduto();
				if(produto.getEstoqueAtual() == null){
					produto.setEstoqueAtual(0.0);
				}
				produto.setEstoqueAtual(produto.getEstoqueAtual()+item.getQuantidade());
				produto = produtoFinalSession.update(produto);
				
			}
		}
		t.setAtualizouEstoque(true);
		PedidoCompra pedido = dao.insert(t);
		atualizarCustoMedio(t);
		return pedido;
	}
	
	private void atualizarCustoMedio(PedidoCompra t) throws ValidacaoException {
		for(ItemCompra item: t.getProdutos()){
			ProdutoFinal produto = item.getProduto();
			produto.setCustoMedio(itemCompraSession.findCustoMedio(produto, item));
			produtoFinalSession.update(produto);
		}
		
	}

	@Override
	public PedidoCompra update(PedidoCompra t) throws ValidacaoException {
		caixaSession.caixaFechado(t.getClinica());
		if(t.getAtualizouEstoque() == null || !t.getAtualizouEstoque()){
			for(ItemCompra item: t.getProdutos()){
				ProdutoFinal produto = item.getProduto();
				if(produto.getEstoqueAtual() == null){
					produto.setEstoqueAtual(0.0);
				}
				produto.setEstoqueAtual(produto.getEstoqueAtual()+item.getQuantidade());
				produto = produtoFinalSession.update(produto);
				
			}
		}
		t.setAtualizouEstoque(true);
		PedidoCompra pedido = dao.update(t);
		atualizarCustoMedio(t);
		return pedido;
	}

}
